home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ohlcpio.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1990-07-07  |  7KB  |  280 lines

  1. /* main.c - main program and argument processing for cpio.
  2.    Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by Philip A. Nelson and David MacKenzie.  */
  19.  
  20. #include <stdio.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #ifndef S_IFLNK
  24. #define lstat stat
  25. #endif
  26. #ifdef USG
  27. #include <string.h>
  28. #else
  29. #include <strings.h>
  30. #endif
  31. #include <getopt.h>
  32. #include "cpio.h"
  33. #include "dstring.h"
  34. #include "extern.h"
  35.  
  36. int lstat ();
  37. int stat ();
  38.  
  39. struct option long_opts[] =
  40. {
  41.   {"binary", 0, &binary_flag, TRUE},
  42.   {"block-size", 1, 0, 130},
  43.   {"create", 0, 0, 'o'},
  44.   {"dereference", 0, 0, 'L'},
  45.   {"extract", 0, 0, 'i'},
  46.   {"link", 0, &link_flag, TRUE},
  47.   {"list", 0, &table_flag, TRUE},
  48.   {"make-directories", 0, &create_dir_flag, TRUE},
  49.   {"nonmatching", 0, ©_matching_files, FALSE},
  50.   {"numeric-uid-gid", 0, &numeric_uid, TRUE},
  51.   {"pass-through", 0, 0, 'p'},
  52.   {"portability", 0, &portability_flag, TRUE},
  53.   {"preserve-modification-time", 0, &retain_time_flag, TRUE},
  54.   {"rename", 0, &rename_flag, TRUE},
  55.   {"reset-access-time", 0, &reset_time_flag, TRUE},
  56.   {"unconditional", 0, &unconditional_flag, TRUE},
  57.   {"verbose", 0, &verbose_flag, TRUE},
  58.   {"version", 0, 0, 'V'},
  59.   {0, 0, 0, 0}
  60. };
  61.  
  62. /*  Print usage message and exit with error.  */
  63.  
  64. void
  65. usage ()
  66. {
  67.   fprintf (stderr, "\
  68. Usage: %s {-o|+create} [-abcvBLV] [+reset-access-time] [+binary]\n\
  69.        [+portability] [+verbose] [+block-size=blocks] [+dereference]\n\
  70.        [+version] < name-list > archive\n\
  71. \n\
  72.        %s {-i|+extract} [-bcdfmnrtuvBV] [+binary] [+portability]\n\
  73.        [+make-directories] [+nonmatching] [+preserve-modification-time]\n\
  74.        [+numeric-uid-gid] [+rename] [+list] [+unconditional] [+verbose]\n\
  75.        [+block-size=blocks] [+version] [pattern...] < archive\n\
  76. \n\
  77.        %s {-p|+pass-through} [-adlLmuvV] [+reset-access-time]\n\
  78.        [+make-directories] [+link] [+preserve-modification-time]\n\
  79.        [+unconditional] [+verbose] [+dereference] [+version]\n\
  80.        destination-directory < name-list\n",
  81.        program_name, program_name, program_name);
  82.   exit (2);
  83. }
  84.  
  85. /* Process the arguments.  Set all options and set up the copy pass
  86.    directory or the copy in patterns.  */
  87.  
  88. void
  89. process_args (argc, argv)
  90.      int argc;
  91.      char *argv[];
  92. {
  93.   extern char *version_string;
  94.   void (*copy_in) ();        /* Work around for pcc bug. */
  95.   void (*copy_out) ();
  96.   int c;
  97.   int longind;
  98.  
  99.   if (argc < 2)
  100.     usage ();
  101.  
  102.   xstat = lstat;
  103.  
  104.   while ((c = getopt_long (argc, argv, "abBcdfilLmnoprtuvV", long_opts,
  105.                &longind)) != EOF)
  106.     {
  107.       switch (c)
  108.     {
  109.     case 0:            /* A long option that just sets a flag. */
  110.       break;
  111.  
  112.     case 'a':        /* Reset access times.  */
  113.       reset_time_flag = TRUE;
  114.       break;
  115.  
  116.     case 'b':        /* Use the nonportable format. */
  117.       binary_flag = TRUE;
  118.       break;
  119.  
  120.     case 'B':        /* Set block size to 5120. */
  121.       io_block_size = 5120;
  122.       break;
  123.  
  124.     case 130:        /* +block-size */
  125.       io_block_size = atoi (optarg);
  126.       if (io_block_size < 1)
  127.         error (2, 0, "invalid block size");
  128.       io_block_size *= 512;
  129.       break;
  130.  
  131.     case 'c':        /* Use the portable format. */
  132.       portability_flag = TRUE;
  133.       break;
  134.  
  135.     case 'd':        /* Create directories where needed.  */
  136.       create_dir_flag = TRUE;
  137.       break;
  138.  
  139.     case 'f':        /* Only copy files not matching patterns. */
  140.       copy_matching_files = FALSE;
  141.       break;
  142.  
  143.     case 'i':        /* Copy-in mode.  */
  144.       if (copy_function != 0)
  145.         usage ();
  146.       copy_function = process_copy_in;
  147.       break;
  148.  
  149.     case 'l':        /* Link files when possible.  */
  150.       link_flag = TRUE;
  151.       break;
  152.  
  153.     case 'L':        /* Dereference symbolic links.  */
  154.       xstat = stat;
  155.       break;
  156.  
  157.     case 'm':        /* Retain previous file modify times. */
  158.       retain_time_flag = TRUE;
  159.       break;
  160.  
  161.     case 'n':        /* Long list owner and group as numbers. */
  162.       numeric_uid = TRUE;
  163.       break;
  164.  
  165.     case 'o':        /* Copy-out mode.  */
  166.       if (copy_function != 0)
  167.         usage ();
  168.       copy_function = process_copy_out;
  169.       break;
  170.  
  171.     case 'p':        /* Copy-pass mode.  */
  172.       if (copy_function != 0)
  173.         usage ();
  174.       copy_function = process_copy_pass;
  175.       break;
  176.  
  177.     case 'r':        /* Interactively rename.  */
  178.       rename_flag = TRUE;
  179.       break;
  180.  
  181.     case 't':        /* Only print a list.  */
  182.       table_flag = TRUE;
  183.       break;
  184.  
  185.     case 'u':        /* Replace all!  Unconditionally!  */
  186.       unconditional_flag = TRUE;
  187.       break;
  188.  
  189.     case 'v':        /* Verbose!  */
  190.       verbose_flag = TRUE;
  191.       break;
  192.  
  193.     case 'V':
  194.       printf ("%s", version_string);
  195.       break;
  196.  
  197.     default:
  198.       usage ();
  199.     }
  200.     }
  201.  
  202.   /* Do error checking and look at other args.  */
  203.  
  204.   if (copy_function == 0)
  205.     {
  206.       if (table_flag)
  207.     copy_function = process_copy_in;
  208.       else
  209.     usage ();
  210.     }
  211.  
  212.   if ((!table_flag || !verbose_flag) && numeric_uid)
  213.     usage ();
  214.  
  215.   /* Work around for pcc bug. */
  216.   copy_in = process_copy_in;
  217.   copy_out = process_copy_out;
  218.  
  219.   if (copy_function == copy_in)
  220.     {
  221.       if (link_flag || reset_time_flag || xstat != lstat
  222.       || (binary_flag && portability_flag))
  223.     usage ();
  224.       if (!binary_flag && !portability_flag)
  225.     binary_flag = portability_flag = TRUE;
  226.       num_patterns = argc - optind;
  227.       save_patterns = &argv[optind];
  228.     }
  229.   else if (copy_function == copy_out)
  230.     {
  231.       if (argc != optind || create_dir_flag || rename_flag
  232.       || table_flag || unconditional_flag || link_flag
  233.       || retain_time_flag || (binary_flag && portability_flag))
  234.     usage ();
  235.     }
  236.   else
  237.     {
  238.       if (argc - 1 != optind || binary_flag || portability_flag
  239.       || table_flag || rename_flag)
  240.     usage ();
  241.       directory_name = argv[optind];
  242.     }
  243. }
  244.  
  245. /* Initialize the input and output buffers to their proper size and
  246.    initialize all variables associated with the input and output
  247.    buffers.  */
  248.  
  249. void
  250. initialize_buffers ()
  251. {
  252.   input_buffer = (char *) xmalloc (io_block_size);
  253.   in_buff = input_buffer;
  254.   input_size = 0;
  255.   input_bytes = 0;
  256.  
  257.   /* Leave space for an `int' sentinel for `empty_output_buffer'. */
  258.   output_buffer = (char *) xmalloc (io_block_size + sizeof (int) * 2);
  259.   out_buff = output_buffer;
  260.   output_size = 0;
  261.   output_bytes = 0;
  262. }
  263.  
  264. void
  265. main (argc, argv)
  266.      int argc;
  267.      char *argv[];
  268. {
  269.   program_name = argv[0];
  270.   umask (0);
  271.  
  272.   process_args (argc, argv);
  273.  
  274.   initialize_buffers ();
  275.  
  276.   (*copy_function) ();
  277.  
  278.   exit (0);
  279. }
  280.